﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Files;
using System.IO;
using System.Configuration;
using System.Xml.Serialization;

namespace FileSynchronizer
{
    /// <summary>
    /// Main class of the application, contains all the logic to make the synchronization.
    /// It has been design to be used as a Singleton.
    /// </summary>
    public class SyncAgent
    {
        private const string CONFIG_FILE = "Config.xml";
        private ConfigItem _config;
        private Guid _localReplicaId = new Guid("{32E755AF-2694-4401-A500-4CFCD331F231}");
        private Guid _remoteReplicaId = new Guid("{5126BD69-0836-455a-97EA-57206B896C5F}");
        
        private SyncAgent()
        {
            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(ConfigItem));
                Stream stream = File.Open(CONFIG_FILE, FileMode.OpenOrCreate);
                _config = serializer.Deserialize(stream) as ConfigItem;
                stream.Close();
            }
            catch (Exception ex)
            {
                throw new ConfigurationErrorsException("Initialization exception:" + ex.Message, ex);
            }
        }

        public string LocalFolder 
        {
            get
            {
                return _config.LocalFolder; 
            }
            set
            {
                try
                {
                    _config.LocalFolder = value;
                    XmlSerializer serializer = new XmlSerializer(typeof(ConfigItem));
                    Stream stream = File.Open(CONFIG_FILE, FileMode.Open);
                    serializer.Serialize(stream, _config);
                    stream.Close();
                }
                catch (Exception ex)
                {
                    throw new ConfigurationErrorsException("Local folder configuration exception:" + ex.Message, ex);
                }
            }
        }

        public string RemoteFolder
        {
            get 
            {
                return _config.RemoteFolder; 
            }
            set
            {
                try
                {
                    _config.RemoteFolder = value;
                    XmlSerializer serializer = new XmlSerializer(typeof(ConfigItem));
                    Stream stream = File.Open(CONFIG_FILE, FileMode.Open);
                    serializer.Serialize(stream, _config);
                    stream.Close();
                }
                catch (Exception ex)
                {
                    throw new ConfigurationErrorsException("Remote folder configuration exception:" + ex.Message, ex);
                }
            }
        }

        private static SyncAgent _instance = new SyncAgent();

        /// <summary>
        /// Unique instance of the class.
        /// </summary>
        public static SyncAgent Instance
        {
            get
            {
                return _instance; 
            }
        }

        /// <summary>
        /// Synchronize the local and remote folder using DownloadUpload direction.
        /// </summary>
        public void Synchronize()
        {
            try
            {
                FileSyncProvider localProvider = new FileSyncProvider(_localReplicaId, LocalFolder);
                FileSyncProvider remoteProvider = new FileSyncProvider(_remoteReplicaId, RemoteFolder);
                SyncOrchestrator syncOrchestrator = new SyncOrchestrator();
                syncOrchestrator.Direction = SyncDirectionOrder.DownloadAndUpload;
                syncOrchestrator.LocalProvider = localProvider;
                syncOrchestrator.RemoteProvider = remoteProvider;
                syncOrchestrator.Synchronize();
            }
            catch (Exception ex)
            {
                throw new SynchronizationException(ex);
            }
        }
    }
}
